package org.dce.screencapturer;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.undo.UndoManager;

import org.dce.screencapturer.actions.DrawingAction;
import org.dce.screencapturer.actions.ScreenCapturerAction;
import org.dce.screencapturer.actions.drawing.CopyToClipboardAction;
import org.dce.screencapturer.actions.drawing.CutUpImageAction;
import org.dce.screencapturer.actions.drawing.PasteFromClipboardAction;
import org.dce.screencapturer.actions.drawing.PrintAction;
import org.dce.screencapturer.actions.drawing.SaveAction;
import org.dce.screencapturer.actions.drawing.SimpleCutImageAction;
import org.dce.screencapturer.actions.objects.AlignCentersHorizontallyAction;
import org.dce.screencapturer.actions.objects.AlignCentersVerticallyAction;
import org.dce.screencapturer.actions.objects.AlignTextBottomAction;
import org.dce.screencapturer.actions.objects.AlignTextCenterAction;
import org.dce.screencapturer.actions.objects.AlignTextLeftAction;
import org.dce.screencapturer.actions.objects.AlignTextMiddleAction;
import org.dce.screencapturer.actions.objects.AlignTextRightAction;
import org.dce.screencapturer.actions.objects.AlignTextTopAction;
import org.dce.screencapturer.actions.objects.AlignToBottomAction;
import org.dce.screencapturer.actions.objects.AlignToLeftAction;
import org.dce.screencapturer.actions.objects.AlignToRightAction;
import org.dce.screencapturer.actions.objects.AlignToTopAction;
import org.dce.screencapturer.actions.objects.BringToBottomAction;
import org.dce.screencapturer.actions.objects.BringToFrontAction;
import org.dce.screencapturer.actions.objects.DecreaseFontSizeAction;
import org.dce.screencapturer.actions.objects.DeleteAction;
import org.dce.screencapturer.actions.objects.EditFillAction;
import org.dce.screencapturer.actions.objects.EditPaintAction;
import org.dce.screencapturer.actions.objects.EditShadowAction;
import org.dce.screencapturer.actions.objects.IncreaseFontSizeAction;
import org.dce.screencapturer.actions.objects.MoveDownAction;
import org.dce.screencapturer.actions.objects.MoveUpAction;
import org.dce.screencapturer.actions.objects.SelectFontAction;
import org.dce.screencapturer.actions.objects.SelectLineWeightAction;
import org.dce.screencapturer.actions.objects.SelectStrokeAction;
import org.dce.screencapturer.actions.objects.SetFontBoldAction;
import org.dce.screencapturer.actions.objects.SetFontItalicAction;
import org.dce.screencapturer.actions.objects.SetFontStrikeThroughAction;
import org.dce.screencapturer.actions.objects.SetFontUnderstrikeAction;
import org.dce.screencapturer.actions.objects.TextColorAction;
import org.dce.screencapturer.actions.ui.CaptureAreaAction;
import org.dce.screencapturer.actions.ui.CaptureScreenshotAction;
import org.dce.screencapturer.actions.ui.ExitAction;
import org.dce.screencapturer.actions.ui.NewImageAction;
import org.dce.screencapturer.actions.ui.NewImageFromClipboardAction;
import org.dce.screencapturer.actions.ui.RedoAction;
import org.dce.screencapturer.actions.ui.UndoAction;
import org.dce.screencapturer.components.ActionPanel;
import org.dce.screencapturer.components.SlideView;
import org.dce.screencapturer.components.SlideViewEvent;
import org.dce.screencapturer.components.SlideViewListener;
import org.dce.screencapturer.components.Toolbar;
import org.dce.screencapturer.objects.Arrow;
import org.dce.screencapturer.objects.Banner;
import org.dce.screencapturer.objects.Box;
import org.dce.screencapturer.objects.Bubble;
import org.dce.screencapturer.objects.Ellipse;
import org.dce.screencapturer.objects.EmptyBox;
import org.dce.screencapturer.objects.Note;
import org.dce.screencapturer.objects.RoundedBox;
import org.dce.screencapturer.objects.StaredEllipse;
import org.dce.screencapturer.objects.Text;

public class UI 
	extends JFrame
	implements SlideViewListener{

	private static final long serialVersionUID = -5358805272020910062L;

	private final Toolbar toolBar = new Toolbar();
	private final SlideView slideView = new SlideView();
	private final JScrollPane drawingContainer = new JScrollPane();
	private final UndoManager undoManager = new UndoManager();
	private SystemTrayHandler handler;
	private ActionCollection drawingActions = new ActionCollection();

	
	public UI(){
		buildDrawingActions();
		buildUI();
		installTryIcon();
	}
	
	private void buildUI(){
		setLayout(new BorderLayout());
		add(toolBar,BorderLayout.NORTH);
		
		add(drawingContainer,BorderLayout.CENTER);
		
		for (String item:new String[]{
			Common.BUNDLE.getString("categories.file"),
			Common.BUNDLE.getString("categories.edit"),
			Common.BUNDLE.getString("categories.draw"),
			Common.BUNDLE.getString("categories.object"),
			Common.BUNDLE.getString("categories.selection"),
			Common.BUNDLE.getString("categories.text")}){
			
			ActionPanel actions = new ActionPanel();
			actions.addActions(DrawingAction.findByCategory(drawingActions, item));
			toolBar.addArea(item, actions);
		}
		
		slideView.addSlideViewListener(this);
		
		add(slideView,BorderLayout.SOUTH);
	}

	private void buildDrawingActions() {
		
		drawingActions.addAll(
			new NewImageAction(),
			new NewImageFromClipboardAction(),
			new CaptureScreenshotAction(),
			new CaptureAreaAction(),
			new SaveAction(),
			new PrintAction(),
			new ExitAction(),
			new CopyToClipboardAction(),
			new PasteFromClipboardAction(),
			new UndoAction(),
			new RedoAction(),
			new Text.InsertAction(),
			new Banner.InsertAction(),
			new Ellipse.InsertAction(),
			new Box.InsertAction(),
			new EmptyBox.InsertAction(),
			new RoundedBox.InsertAction(),
			new Bubble.InsertAction(),
			new StaredEllipse.InsertAction(),
			new Note.InsertAction(),
			new Arrow.InsertAction(),
			new EditFillAction(),
			new EditPaintAction(),
			new EditShadowAction(),
			new DeleteAction(),
			new AlignToLeftAction(),
			new AlignToRightAction(),
			new AlignCentersHorizontallyAction(),
			new AlignToBottomAction(),
			new AlignToTopAction(),
			new AlignCentersVerticallyAction(),
			new SimpleCutImageAction(),
			new SelectStrokeAction(),
			new SelectLineWeightAction(),
			new CutUpImageAction(),
			new SetFontBoldAction(),
			new SetFontItalicAction(),
			new SetFontUnderstrikeAction(),
			new SetFontStrikeThroughAction(),
			new IncreaseFontSizeAction(),
			new DecreaseFontSizeAction(),
			new SelectFontAction(),
			new AlignTextLeftAction(),
			new AlignTextCenterAction(),
			new AlignTextRightAction(),
			new AlignTextTopAction(),
			new AlignTextMiddleAction(),
			new AlignTextBottomAction(),
			new TextColorAction(),
			new BringToFrontAction(),
			new BringToBottomAction(),
			new MoveUpAction(),
			new MoveDownAction());
		
		for (ScreenCapturerAction action:drawingActions){ 
			action.setUI(this); 
		}
	}
	
	private void setCurrentDrawing(Drawing drawing){
		drawingContainer.getViewport().setView(drawing);
		
		drawingContainer.getViewport().doLayout();

		for (ScreenCapturerAction drawingAction:drawingActions){
			if (drawingAction instanceof DrawingAction){
				((DrawingAction)drawingAction).setDrawing(drawing);
			}
		}
	}
	
	public Drawing getCurrentDrawing(){
		return (Drawing)drawingContainer.getViewport().getView();
	}
	
	public void addDrawing(Drawing drawing){
		drawing.setUI(this);
		slideView.addDrawing(drawing);
		slideView.selectDrawing(drawing);
		validate();
	}

	public void addNewImageFromClipboard(){
		try {
			Clipboard clipboard = getToolkit().getSystemClipboard();
			
			if (clipboard.isDataFlavorAvailable(DataFlavor.imageFlavor)){
				Object data = clipboard.getData(DataFlavor.imageFlavor);
				
				if (data != null && data instanceof BufferedImage){
					addImageAsDrawing((BufferedImage)data);
				}
				showUI();
			} 
			
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
	
	public void addImageAsDrawing(BufferedImage image){
		addDrawing(new Drawing(image));
	}
	
	public ActionCollection getActions(){
		return drawingActions;
	}
	
	public UndoManager getUndoManager(){
		return undoManager;
	}
	
	public static void main(String[] args){
		try {
//			UIManager.setLookAndFeel(CustomLookAndFeel.class.getName());
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		}catch (Exception ex){
		}
		UI ui = new UI();
		ui.setMinimumSize(new Dimension(640,480));
		ui.setPreferredSize(Toolkit.getDefaultToolkit().getScreenSize());
		ui.showUI();
	}
	
	public void showUI(){
		if (!isVisible()){
			setPreferredSize(Toolkit.getDefaultToolkit().getScreenSize());
			setVisible(true);
			setExtendedState(UI.MAXIMIZED_BOTH);
		}
		toFront();
	}
	
	public void hideUI(){
		if (isVisible()){
			setVisible(false);
		}
	}
	
	public void toggleShowUI(){
		if (isVisible()){
			setVisible(false);
		} else {
			showUI();
		}
	}

	private void installTryIcon() {
		try {
			handler = new SystemTrayHandler(this);
		}catch (Exception ex){
			ex.printStackTrace();
		}
	}

	
	
	@Override
	public void drawingAdded(SlideViewEvent event) {
		setCurrentDrawing(event.getDrawing());
	}

	@Override
	public void drawingRemoved(SlideViewEvent event) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void drawingSelected(SlideViewEvent event) {
		setCurrentDrawing(event.getDrawing());
	}

	public void exit() {
		handler.close();
		System.exit(0);
	}
	
}
